// TODO: FOR RELEASE, MAKE SURE NOT TO RELEASE A DEBUG VERSION. THAT MAY
 //CONTAIN ORIGINAL SOURCE CODE INFORMATION

/***************************************************************************
                          qtrack.h  -  description
                             -------------------
    begin                : Mon Dec 24 2001
    copyright            : (C) 2001 by Juan F. Herrera
    email                : juanfh@users.SPAMMENOT.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 See the file "legal.txt" for terms governing usage, redistribution, and
 modification of this source code.
 ***************************************************************************/

#ifndef __QTRACK_H
#define __QTRACK_H

#ifndef QTRK_FP
#define QTRK_FP float
#endif
#ifndef FP
#define FP QTRK_FP
#endif

// global tracker variables
#ifdef __cplusplus
#define EXTERN_TYPE extern "C"
#else
#define EXTERN_TYPE extern 
#endif

// NOTE THAT FIELD VARIABLES ARE FLOATING POINT. IT WOULD BE A BIT DIFFICULT TO USE
// INTEGERS, AS CALIBRATION GETS US NON-INTEGERS. FIXED POINT WOULD BE FEASIBLE, BUT
// THAT WOULD REQUIRE SOME CARE

	EXTERN_TYPE FP qtrk_coil_field_comp[6][3];
	EXTERN_TYPE FP qtrk_orientation_coil_field_comp[3][3];	// difference of opposite axes fields for orientation calculation
	EXTERN_TYPE FP qtrk_coil_field_mag[6];						// fields for each coil
	EXTERN_TYPE FP qtrk_ref_field[3];					// reference fields, float
//	EXTERN_TYPE int qtrk_ref_idx[3];						// indices of selected reference coils

// used internally by qtrack.c, available globally for debugging
    EXTERN_TYPE FP field_coord[3];
	
	EXTERN_TYPE FP qtrk_tracker_pos[3];			// position

	EXTERN_TYPE FP qtrk_orientation[4][4];

	// jfh hack INSERT B_field, B_mag here
	
	// inverse point matrix
	// TODO: try const int
	// also need floating point versions for optimizing calculation of field_coord
	EXTERN_TYPE int	qtrk_min_field;
	EXTERN_TYPE int qtrk_max_field;
	EXTERN_TYPE int qtrk_field_step;
	EXTERN_TYPE QTRK_FP qtrk_field_step_fp;
	EXTERN_TYPE int qtrk_adc_mult_const;
	EXTERN_TYPE QTRK_FP qtrk_bfield_norm_const;

//	EXTERN_TYPE QTRK_FP *qtrk_inv_matrix_ng;

	EXTERN_TYPE int qtrk_matrix_full_dim_p1;
//	EXTERN_TYPE int qtrk_matrix_full_dim_p2;

	EXTERN_TYPE FP Bfield[6][3];
	EXTERN_TYPE FP Bmag_axis[3];
	EXTERN_TYPE FP Bmag[6];

// todo: verify status stuff

	typedef struct {
		int success;
		int ref_field_off_range_flag;
		int ref_field_off_range[6];
		int interpolation_base_success;
		int interpolation_edge_success[8];
		int interpolation_edge_fail;
		int interpolation_edge_number;
		int reference_quadrant_flag;
	} qtrk_status_descriptor;

	EXTERN_TYPE qtrk_status_descriptor qtrk_status_global;					// tracking status

// data structure for tracker nodes. these contain data that is
// obtained upon sampling (qtrk_coil_field_comp, qtrk_ref_idx,
// qtrk_ref_field_int,qtrk_ref_idx), and the position and orientation
// results.

typedef struct {
	FP coil_field_comp[6][3];
} qtrk_node;

// We frequently operate on an array of nodes. We may use an internal node list.
// However, one may use an external one (just duplicate this.)
EXTERN_TYPE int qtrk_n_nodes;
EXTERN_TYPE qtrk_node *qtrk_node_array;
EXTERN_TYPE QTRK_FP qtrk_pos_array[16][3];
EXTERN_TYPE QTRK_FP qtrk_orientation_array[16][4][4];

// jfh 2006 oct 10
EXTERN_TYPE void newton(FP pos_in[], FP pos_next[]);

#ifdef __cplusplus
extern "C" {
#endif

void qtrk_init_inv_matrix(char *);
// One may use qtrk_read_node(), then the functions below.
void qtrk_get_direct_tracker_position(void);
void qtrk_interpolate_tracker_position(void);
void qtrk_get_tracker_orientation(void);
void qtrk_get_tracker_orientation_skewed(void);
// The functions above can be accessed by nodes.
void qtrk_read_node(qtrk_node *);
// void qtrk_allocate_nodes(int n_nodes_arg);
void qtrk_set_parameters(qtrk_node *node_array_arg,int n_nodes_arg);
void qtrk_process_node_array(void);
void qtrk_process_single_node(qtrk_node *);
// Wrapper intended for working with JNI, using SWIG.
float qtrk_read_pos_array(int, int);
//void qtrk_process_node_array(void);

//void qtrk_get_tracker_position_node(FP *,qtrk_status_descriptor *);
//void qtrk_get_tracker_position_node_calib(FP [][3],qtrk_status_descriptor []);



//void qtrk_set_active_node(qtrk_node *);
//void qtrk_retrieve_result_to_node(qtrk_node *);
// TODO: LOSE
// void qtrk_get_tracker_data(void);
// void qtrk_get_tracker_data_filt(void);

/* temporarily duplicated trkdrv routines for vc++.net framework */
void qtrkdrv_init(void);

/*
 * utility macros
 */ 

// TODO: macro below shouldn't be necessary when tracker coords are consistent with
// physical
#define COORD_TRK_TO_PHYS(x,y,z) (z),(x),(y)

/*
 * obsolete stuff
 */

#define MAX_RATIO_RANGE 1.68
#define MIN_RATIO_RANGE 0.6

//	EXTERN_TYPE FP minFieldRatio;
//	EXTERN_TYPE int minFieldRatioIdx;
//	EXTERN_TYPE FP uncalibratedposFieldRatio;

	
//	EXTERN_TYPE FP qtrk_axis_field_ratio[3];
//	EXTERN_TYPE int fieldRatioIdx[3];

// Functions in bfield.c
void calculate_cube_B(float, float, float);

#ifdef __cplusplus
}
#endif

#endif // __QTRACK_H
